#include "mystdio.h"

#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <assert.h>
#include <errno.h>

MY_FILE *my_fopen(const char *path, const char *mode)
{
    int fd = 0;
    int flag = 0;
    if (strcmp(mode, "r") == 0)
    {
        flag = O_RDONLY;
    }
    else if (strcmp(mode, "w") == 0)
    {
        flag = (O_WRONLY | O_CREAT | O_TRUNC); 
    }
    else if (strcmp(mode, "a") == 0)
    {
        flag = (O_WRONLY | O_CREAT | O_APPEND);
    }
    else
    {
        // do nothing
    }
    if (flag == 0)
    {
        // 打卡方式不对
        errno = 1;
        return NULL;
    }

    if (flag | O_CREAT)
        fd = open(path, flag, 0666);
    else 
        fd = open(path, flag);

    if (fd == -1)
    {
        // 打开文件失败
        errno = 2;
        return NULL;
    }
    MY_FILE* fp = (MY_FILE*)malloc(sizeof(MY_FILE));
    if (fp == NULL)
    {
        errno = 3;
        return NULL;
    }
    fp->fileno = fd;
    fp->end = 0;

    return fp;
}

int my_fclose(MY_FILE *fp)
{
    assert(fp != NULL);
    my_fflush(fp);
    return close(fp->fileno);
}

int my_fputs(const char *s, MY_FILE *stream)
{
    assert(stream != NULL);

    strcpy(stream->buffer + stream->end, s);
    int len = strlen(s);
    stream->end += len;

    //循环判断是否存在\n
    for (int i = 0; i < stream->end; i++)
    {
        if (stream->buffer[i] == '\n')
        {
            //刷新[0, i]的所有内容
            write(stream->fileno, stream->buffer, i + 1);
            strcpy(stream->buffer, stream->buffer + i + 1);
            stream->end -= i + 1;
        }
    }

    //返回插入的个数
    return len;
}


int my_fflush(MY_FILE *stream)
{
    assert(stream != NULL);
    //将数据刷新到内核缓冲区
    if (stream->end > 0)
    {
        write(stream->fileno, stream->buffer, stream->end);
        fsync(stream->fileno);

        stream->end = 0;
    }

    return 0;
}
